package someTestExcemple.collectionAndMap.map;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * LinkedHashMap 是 Java 集合框架中的一个实现类，
 * 它继承自 HashMap，并且保留了键值对的插入顺序或访问顺序。
 *
 * 它内部是通过维护了
 * 一个双向链表(首先它把 HashMap 的 Entry 加了两个指针：before 和 after。)
 * 来记录元素的插入顺序或访问顺序。
 * 使用场景：
 * 缓存实现：可以根据访问顺序移除最久未使用的元素，
 * 常用于 LRU（Least Recently Used）缓存。
 * 数据存储：需要保持元素插入顺序的场景。
 */


public class LinkedHashMapLearning {
    public static void main(String[] args) {
        //LinkedHashMap 继承了 HashMap 的大多数操作，如 put、get、remove 等。它的主要功能是能够保持键值对的顺序。
        //默认是按插入顺序排序
        LinkedHashMap<String, String> linkedHashMap1 = new LinkedHashMap<>();
        linkedHashMap1.put("1", "1");
        linkedHashMap1.put("2", "2");
        linkedHashMap1.put("3", "3");
        for(Map.Entry<String, String> entry : linkedHashMap1.entrySet()) {
            System.out.println(entry.getKey() + " -> " + entry.getValue());
        }
        //也可以设置按访问顺序排序，通过指定 accessOrder 参数为 true
        // 每次访问元素后顺序会发生变化，当访问某个键时（通过 get 或 put），
        // 该键值对会被移到链表的末尾，从而修改迭代顺序。
        System.out.println("=================================");
        LinkedHashMap<Integer, String> map = new LinkedHashMap<>(16, 0.75f, true);
        map.put(1, "one");
        map.put(2, "two");
        map.put(3, "three");
        map.get(2); // 访问 key 为 2 的元素

        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + " -> " + entry.getValue());
        }
        // 输出顺序为：1 -> one, 3 -> three, 2 -> two
        System.out.println("======================================");
        //LinkedHashMap 提供了一个特殊的钩子方法 removeEldestEntry，它允许用户在每次插入新元素时决定是否删除最旧的元素（即链表的头部）。
        // 这是实现LRU（Least Recently Used）缓存的一种常见方式。
        //可以重写 removeEldestEntry 方法，控制缓存的最大容量：
        LinkedHashMap<Integer, String> lruCache = new LinkedHashMap<Integer, String>(16, 0.75f, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<Integer, String> eldest) {
                return size() > 3; // 当缓存大小超过 3 时，移除最旧的元素
            }
        };
        lruCache.put(1, "one");
        lruCache.put(2, "two");
        lruCache.put(3, "three");
        lruCache.put(4, "four"); // 插入新元素后，最旧的元素（1 -> one）会被移除
        for(Map.Entry<Integer, String> entry : lruCache.entrySet()) {
            System.out.println(entry.getKey() + " -> " + entry.getValue());
        }
    }
}
